home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / news / misc / newsxd-2.5.1-shar / config.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-08  |  27.9 KB  |  797 lines

  1. /*
  2.  * #include <legal/bs.h>
  3.  >
  4.  > Copyright (c) 1989 Washington University in Saint Louis, Missouri and
  5.  > Chris Myers. All rights reserved.
  6.  >
  7.  > Permission is hereby granted to copy, reproduce, redistribute or
  8.  > otherwise use this software as long as: (1) there is no monetary
  9.  > profit gained specifically from the use or reproduction of this
  10.  > software, (2) it is not sold, rented, traded, or otherwise marketed,
  11.  > (3) the above copyright notice and this paragraph is included
  12.  > prominently in any copy made, and (4) that the name of the University
  13.  > is not used to endorse or promote products derived from this software
  14.  > without the specific prior written permission of the University.
  15.  > THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  > IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  > WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  >
  19.  */
  20.  
  21. #include "defs.h"
  22.  
  23. /*************************************************************************/
  24. /* FUNCTION  : getclass                                                  */
  25. /* PURPOSE   : Return a pointer to the class structure given the name of */
  26. /*             a class                                                   */
  27. /* ARGUMENTS : The name of a class                                       */
  28. /*************************************************************************/
  29.  
  30. struct class *
  31. getclass(classname)
  32.    char *classname;
  33.  
  34. {
  35. struct  class   *classptr;
  36.  
  37.    if (strlen(classname) > MAXCLASSNAMELEN - 1) {
  38.       Dprintf("(getclass): classname %s is too long, no match\n", classname);
  39.       return((struct class *) NULL);
  40.    }
  41.  
  42.    foreach (classptr, classlist) {
  43.       Dprintf("(getclass): now checking class %s\n", classptr->classname);
  44.       if (strcmp(classname, classptr->classname) == 0) break;
  45.    }
  46.  
  47.    return(classptr);
  48.  
  49. }
  50.  
  51. /*************************************************************************/
  52. /* FUNCTION  : addclass                                                  */
  53. /* PURPOSE   : Add a class to or modify a class in the class list        */
  54. /* ARGUMENTS : All the information needed to define a class...           */
  55. /*************************************************************************/
  56.  
  57. void
  58. addclass(classname,maxxmits,interval,startint,maxload,ttl,ttlpenalty,nice,flags,         debugflags)
  59.    char *classname, *debugflags;
  60.    int  maxxmits, interval, startint, maxload, ttl, ttlpenalty, nice, flags;
  61.  
  62. {
  63. struct  class   *classptr = classlist;
  64. char    *flagbuf;
  65. int     loop,
  66.         newclass = 0;
  67.  
  68.    if (strlen(classname) > MAXCLASSNAMELEN - 1) {
  69.       logerr("(addclass) Class name %s too long, max %d - ignoring\n",
  70.          classname, MAXCLASSNAMELEN - 1);
  71.       return;
  72.    }
  73.  
  74.    if ((classptr = getclass(classname)) == NULL) {
  75.       Dprintf("(addclass): CALLOCing new class structure\n");
  76.       classptr = (struct class *) calloc(1, sizeof(struct class));
  77.       if (classptr == NULL) {
  78.          logerr("(addclass) Can't calloc struct class for class %s\n",
  79.             classname);
  80.          return;
  81.       }
  82.       for (loop = 0; loop < MAXCLASSXMITTERS; loop++)
  83.          classptr->slots[loop] = '.';
  84.       newclass++;
  85.    } else if (classptr->valid == 1) {
  86.       logerr("(addclass) Duplicated class %s\n", classname);
  87.       return;
  88.    }
  89.  
  90.    /*
  91.     * Build class structure for this class and insert at the head of the
  92.     * class list
  93.     */
  94.  
  95.    (void) strcpy(classptr->classname, classname);
  96.    classptr->maxxmits = maxxmits;
  97.    classptr->options.maxload = maxload;
  98.    classptr->options.interval = interval;
  99.    classptr->options.startint = startint;
  100.    classptr->options.ttl = ttl;
  101.    classptr->options.deltanice = nice;
  102.    classptr->options.ttlpenalty = ttlpenalty;
  103.    classptr->valid = 1;
  104.    classptr->xmitsernum = 0;
  105.    classptr->members = 0;
  106.    classptr->debugargc = 0;
  107.  
  108.    if (debug && strlen(debugflags) > 0) {
  109.       if ((flagbuf = (char *) calloc(1, strlen(debugflags) + 1)) != NULL) {
  110.          (void) strcpy(flagbuf, debugflags);
  111.          while (1) {
  112.             classptr->debugargv[classptr->debugargc++] = flagbuf;
  113.             if ((flagbuf = STRCHR(flagbuf, '|')) == (char *) NULL) break;
  114.             *flagbuf++ = '\0';
  115.          }
  116.          Dprintf("(addclass) %s: debugargc = %d\n", classname,
  117.             classptr->debugargc);
  118.       }
  119.    }
  120.  
  121.    /*
  122.     * Set all of the class flags.  flag is a bitmap.
  123.     */
  124.  
  125.    for (loop = 0; loop < MAXCLASSFLAGS; loop++) {
  126.       if (flags & (1 << loop))
  127.          classptr->flags[loop] = 1;
  128.       else
  129.          classptr->flags[loop] = 0;
  130.       Dprintf("(addclass): flags[%d] = %d\n", loop,
  131.          classptr->flags[loop]);
  132.    }
  133.  
  134.    /*
  135.     * Check to see if we are just overwriting a class description, if so don't
  136.     * wipe the pointer to the next entry in the list.
  137.     */
  138.  
  139.    if (newclass) {
  140.       classptr->next = classlist;
  141.       classlist = classptr;
  142.    }
  143.  
  144.    Dprintf("(addclass): classlist = %d\n", classlist);
  145. }
  146.  
  147. /*************************************************************************/
  148. /* FUNCTION  : addhost                                                   */
  149. /* PURPOSE   : Add a host to the list of hosts to transmit to            */
  150. /* ARGUMENTS : Name of the host, class name, start and stop times        */
  151. /*************************************************************************/
  152.  
  153. void
  154. addhost(hostname, classname, times, deltanice, maxload, interval, startint,
  155.     ttl, ttlpenalty, flags)
  156.  
  157.    char *hostname, *classname, *times, *flags;
  158.    int  deltanice, maxload, interval, startint, ttl, ttlpenalty;
  159.  
  160. {
  161. struct  host    *hostptr,
  162.                 *loopptr,
  163.                 *lastptr = NULL;
  164. struct  class   *classptr;
  165. int     loop;
  166. char    *flagbuf;
  167.  
  168.    if (strlen(hostname) > MAXHOSTNAMELEN - 1) {
  169.       logerr("(addhost) Host name %s too long, max %d - ignoring\n",
  170.          classname, MAXHOSTNAMELEN - 1);
  171.       return;
  172.    }
  173.  
  174.    if (strlen(times) > MAXTIMENAMELEN - 1) {
  175.       logerr("(addhost) Host time %s too long, max %d - ignoring\n",
  176.          classname, MAXTIMENAMELEN - 1);
  177.       return;
  178.    }
  179.  
  180.    if ((classptr = getclass(classname)) == NULL) {
  181.       logerr("(addhost) Host's (%s) class %s doesn't exist - ignoring host\n",
  182.          hostname, classname);
  183.       return;
  184.    }
  185.  
  186.    if (classptr->valid == 0) {
  187.       logerr("(addhost) Host's (%s) class %s is invalid - ignoring host\n",
  188.          hostname, classname);
  189.       return;
  190.    }
  191.  
  192.    if (strcmp(classname, "DEFAULT") == 0) {
  193.       logerr("(addhost) Host (%s) can't be a member of class DEFAULT\n",
  194.          hostname);
  195.       return;
  196.    }
  197.  
  198.    lastptr = NULL;
  199.    foreach (hostptr, hostlist) {
  200.       Dprintf("(addhost): now checking host %s\n", hostptr->hostname);
  201.       if (strcmp(hostname, hostptr->hostname) == 0) break;
  202.       lastptr = hostptr;
  203.    }
  204.  
  205.    if (hostptr != NULL) {
  206.       if (hostptr->valid == 1) {
  207.          logerr("(addhost) Duplicated host %s\n", hostname);
  208.          return;
  209.       }
  210.       if (lastptr != NULL) {
  211.          lastptr->next = hostptr->next;
  212.          Dprintf("(addhost) host %s next was %s, now %s\n", lastptr->hostname,
  213.             hostptr->hostname, hostptr->next ? hostptr->next->hostname : NULL);
  214.       } else
  215.          hostlist = hostptr->next;
  216.    } else {
  217.       Dprintf("(addhost): CALLOCing new host structure\n");
  218.       hostptr = (struct host *) calloc(1, sizeof(struct host));
  219.       if (hostptr == NULL) {
  220.          logerr("(addhost) Can't calloc struct host for host %s\n",
  221.             hostname);
  222.          return;
  223.       }
  224.    }
  225.  
  226.    (void) strcpy(hostptr->hostname, hostname);
  227.    (void) strcpy(hostptr->class, classname);
  228.    (void) strcpy(hostptr->times, times);
  229.    hostptr->valid = 1;
  230.    hostptr->options.deltanice = deltanice;
  231.    hostptr->options.maxload = maxload;
  232.    hostptr->options.interval = interval;
  233.    hostptr->options.startint = startint;
  234.    hostptr->options.ttl = ttl;
  235.    hostptr->options.ttlpenalty = ttlpenalty;
  236.    hostptr->xmitsernum = 0;
  237.    hostptr->xargc = 0;
  238.    classptr->members++;
  239.  
  240.    if (flags && strlen(flags) > 0) {
  241.       if ((flagbuf = (char *) calloc(1, strlen(flags) + 1)) != NULL) {
  242.          (void) strcpy(flagbuf, flags);
  243.          while (1) {
  244.             hostptr->xargv[hostptr->xargc++] = flagbuf;
  245.             if ((flagbuf = STRCHR(flagbuf, '|')) == (char *) NULL) break;
  246.             *flagbuf++ = '\0';
  247.          }
  248.       }
  249.    }
  250.  
  251.    for (loop = 0; loop < hostptr->xargc; loop++)
  252.       Dprintf("host %s: flag[%d] = %s\n", hostname, loop, hostptr->xargv[loop]);
  253.  
  254.    /*
  255.     * If this is a new host, do a two-key insertion sort based on the
  256.     * hostname and name of the transmission class.  Makes things look nice
  257.     * in the status display...
  258.     */
  259.  
  260.    lastptr = NULL;
  261.  
  262.    if (hostlist == NULL) {
  263.       Dprintf("(addhost): %s IS hostlist now\n", hostname);
  264.       hostlist = hostptr;
  265.    } else {
  266.       foreach (loopptr, hostlist) {
  267.          if (((strcmp(hostptr->hostname, loopptr->hostname) < 0) &
  268.              (strcmp(hostptr->class, loopptr->class) == 0)) | 
  269.              (strcmp(hostptr->class, loopptr->class) < 0)) {
  270.             Dprintf("(addhost): Inserting %s before %s\n", hostname,
  271.                loopptr->hostname);
  272.             hostptr->next = loopptr;
  273.             if (lastptr != NULL) lastptr->next = hostptr;
  274.             if (loopptr == hostlist) hostlist = hostptr;
  275.             break;
  276.          }
  277.          lastptr = loopptr;
  278.       }
  279.       if (loopptr == NULL) {
  280.          Dprintf("(addhost): appending host %s to hostlist\n", hostname);
  281.          lastptr->next = hostptr; /* append to current host list */
  282.          hostptr->next = NULL;
  283.       }
  284.    }
  285.    Dprintf("(addhost): hostlist = %d\n", hostlist);
  286. }
  287.  
  288. /*************************************************************************/
  289. /* FUNCTION  : make_invalid                                              */
  290. /* PURPOSE   : Mark all hosts and classes as invalid                     */
  291. /* ARGUMENTS : none                                                      */
  292. /*************************************************************************/
  293.  
  294. void
  295. make_invalid()
  296.  
  297. {
  298. struct  class   *classptr,
  299.                 *nextclass;
  300. struct  host    *hostptr,
  301.                 *nexthost;
  302.  
  303.    dprintf("(make_invalid) marking all classes as invalid\n");
  304.    for (classptr = classlist; classptr != NULL; classptr = nextclass) {
  305.       Dprintf("(make_invalid) marking class %s as invalid\n",
  306.          classptr->classname);
  307.       classptr->valid = 0;
  308.       classptr->members = 0;
  309.       nextclass = classptr->next;
  310.    }
  311.  
  312.    dprintf("(make_invalid) marking all hosts as invalid\n");
  313.    for (hostptr = hostlist; hostptr != NULL; hostptr = nexthost) {
  314.       Dprintf("(make_invalid) marking host %s as invalid\n", hostptr->hostname);
  315.       hostptr->valid = 0;
  316.       nexthost = hostptr->next;
  317.    }
  318.  
  319. }
  320.  
  321. /*************************************************************************/
  322. /* FUNCTION  : clear_invalid                                             */
  323. /* PURPOSE   : Remove all hosts and classes which are not valid anymore  */
  324. /* ARGUMENTS : none                                                      */
  325. /*************************************************************************/
  326.  
  327. void
  328. clear_invalid()
  329.  
  330. {
  331. struct  class   *lastclass = NULL,
  332.                 *classptr,
  333.                 *nextclass;
  334. struct  host    *lasthost = NULL,
  335.                 *hostptr,
  336.                 *nexthost;
  337. int     loop;
  338.  
  339.    dprintf("(clear_invalid) clearing all invalid hosts\n");
  340.    for (hostptr = hostlist; hostptr != NULL; hostptr = nexthost) {
  341.       nexthost = hostptr->next;
  342.       if (hostptr->valid == 0) {
  343.          if (hostptr->pid > 0) {
  344.             dprintf("(clear_invalid): killing transmitter for host %s\n",
  345.                hostptr->hostname);
  346.             if (kill(hostptr->pid, SIGTERM) != 0) xmit_done(-hostptr->pid);
  347.          }
  348.          Dprintf("(clear_invalid): clearing host %s\n", hostptr->hostname);
  349.          if (hostlist == hostptr) hostlist = nexthost;
  350.          (void) free(hostptr);
  351.          if (lasthost) lasthost->next = nexthost;
  352.       } else {
  353.          lasthost = hostptr;
  354.       }
  355.    }
  356.  
  357.    dprintf("(clear_invalid) clearing all invalid classes\n");
  358.    for (classptr = classlist; classptr != NULL; classptr = nextclass) {
  359.       nextclass = classptr->next;
  360.       if (classptr->valid == 0) {
  361.          Dprintf("(clear_invalid): clearing class %s\n", classptr->classname);
  362.          for (loop = 0; loop < classptr->xargc; loop++) {
  363.             Dprintf("(clear_invalid): clearing class %s argv %d\n",
  364.                classptr->classname, loop);
  365.             (void) free(classptr->xargv[loop]);
  366.          }
  367.          if (classlist == classptr) classlist = nextclass;
  368.          (void) free(classptr);
  369.          if (lastclass) lastclass->next = nextclass;
  370.       } else {
  371.          lastclass = classptr;
  372.       }
  373.    }
  374. }
  375.  
  376. /*************************************************************************/
  377. /* FUNCTION  : read_config                                               */
  378. /* PURPOSE   : Read the newsxd configuration file                        */
  379. /* ARGUMENTS : none                                                      */
  380. /*************************************************************************/
  381.  
  382. void
  383. read_config(sig)
  384.    int  sig;
  385.  
  386. {
  387. FILE    *config;
  388.  
  389. char    line[MAXPATHLEN],       /* buffer used for inputting lines           */
  390.         buf[10][MAXPATHLEN],    /* buffers for various command parameters    */
  391.         *comment;               /* used to trim comments from input lines    */
  392.  
  393. int     loop,
  394.         deltanice,              /* Amount to change proc's nice for xmit     */
  395.         optioncnt,              /* number of parameters found by sscanf      */
  396.         maxxmits,               /* number of allowed simul. transmitters     */
  397.         interval,               /* interval between xmits to a single host   */
  398.         startint,               /* interval between starting xmits 4 a class */
  399.         maxload,                /* max allowed load for starting new xmits   */
  400.         ttl,                    /* maximum time-to-live for a transmitter    */
  401.         ttlpenalty,             /* time penalty for exceeding ttl            */
  402.         flags;                  /* option flags for this transmission class  */
  403.  
  404. struct  class   *classptr;      /* used to traverse the class list           */
  405. struct  stat    statbuf;
  406.  
  407.    if (!(config = fopen(configfile, "r"))) {
  408.       logerr("Couldn't open config file (%s) - aborting\n", configfile);
  409.       (void) exit(1);
  410.    }
  411.  
  412.    /*
  413.     * Mark all hosts and classes as undefined, but don't delete 'em yet
  414.     */
  415.  
  416.    if (sig) log(LOG_INFO, "reinitializing\n");
  417.  
  418.    make_invalid();
  419.  
  420.    CONFIGCHANGED = 1;
  421. #ifdef FAKESYSLOG
  422.    CONFIGCHANGEDFILE = 1;
  423. #endif
  424.    daemon_idle = 0; /* Allow newsxd to begin running the queue again */
  425.  
  426.    /*
  427.     * Reset all of the various data files to their default location
  428.     */
  429.  
  430.    (void) strcpy(batchfile, default_batchfile);
  431.    (void) strcpy(workfile, default_workfile);
  432.    (void) strcpy(xmitlogs, default_xmitlogs);
  433.  
  434.    locking  = 0;                /* locking defaults to OFF                */
  435.    tallying = 0;                /* use of the tally file defaults to OFF  */
  436.    queueinterval = 60;          /* default queue run interval of 1 minute */
  437.  
  438.    /*
  439.     * Add the DEFAULT pseudo-class so that a default xmitter can be specified
  440.     */
  441.  
  442.    addclass("DEFAULT", 0, 0, 0, 0, 0, 0, 0, 0, 0);
  443.  
  444.    while (fgets(line, 255, config) != NULL) {
  445.  
  446.       if ((comment = index(line, '#')) != NULL)
  447.          (void) strcpy(comment, "\n");
  448.  
  449.       Dprintf("> %s", line);
  450.  
  451.       if (sscanf(line, "tallyfile %s\n", tallyfile) > 0) {
  452.          dprintf("tallyfile is %s\n", tallyfile);
  453.          tallying = 1;
  454.       }
  455.  
  456.       if (sscanf(line, "batchfile %s\n", batchfile) > 0)
  457.          dprintf("batchfile is %s\n", batchfile);
  458.  
  459.       if (sscanf(line, "xmitlogs %s\n", xmitlogs) > 0) {
  460.          dprintf("xmitlogs is %s\n", xmitlogs); continue; }
  461.  
  462.       if (sscanf(line, "workfile %s\n", workfile) > 0)
  463.          dprintf("workfile is %s\n", workfile);
  464.  
  465.       if (sscanf(line, "queueinterval %d\n", &queueinterval) > 0)
  466.          dprintf("queueinterval is %d\n", queueinterval);
  467.  
  468.       if ((optioncnt = sscanf(line, "class %s %s %s %s %s %s %s %s", buf[0],
  469.          buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8])) > 0) {
  470.  
  471.          maxxmits = 1;
  472.          interval = 60;
  473.          startint = 0;
  474.          maxload = 99;
  475.          ttl = 999999;
  476.          ttlpenalty = 0;
  477.          flags = 0;
  478.          deltanice = 0;
  479.          *buf[9] = '\0';
  480.  
  481.          Dprintf("optioncnt = %d\n", optioncnt);
  482.  
  483.          for (loop = 1; loop < optioncnt; loop++) {
  484.             (void) sscanf(buf[loop], "maxxmits=%d", &maxxmits);
  485.             (void) sscanf(buf[loop], "maxload=%d", &maxload);
  486.             (void) sscanf(buf[loop], "nice=%d", &deltanice);
  487.             (void) sscanf(buf[loop], "interval=%d/%d", &interval, &startint);
  488.             (void) sscanf(buf[loop], "ttl=%d/%d", &ttl, &ttlpenalty);
  489.             (void) sscanf(buf[loop], "debug=%s", buf[9]);
  490.             if (strcmp(buf[loop], "noworkfile") == 0) flags |= (1<<C_NOWORK);
  491.             if (strcmp(buf[loop], "nobatchfile") == 0) flags |= (1<<C_NOBATCH);
  492.          }
  493.  
  494.          dprintf("class %s, maxxmits %d, intvl %d/%d, maxload %d, ttl %d/%d, nice %d, flags=%d, debug=%s\n",
  495.             buf[0], maxxmits, interval, startint, maxload, ttl, ttlpenalty,
  496.             deltanice, flags, buf[9]);
  497.  
  498.          addclass(buf[0], maxxmits, interval, startint, maxload, ttl,
  499.                   ttlpenalty, deltanice, flags, buf[9]);
  500.       }
  501.  
  502.       if ((optioncnt = sscanf(line, "xmit %s %s %s %s %s %s %s %s %s", buf[0],
  503.          buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8])) > 0) {
  504.  
  505.          classptr = getclass(buf[0]);
  506.          if (!classptr | (classptr->valid == 0)) {
  507.             logerr("(read_config) xmit class for invalid class %s ignored\n",
  508.                buf[0]);
  509.          }
  510.  
  511.          if (stat(buf[1], &statbuf) != 0) {
  512.             logerr("(read_config) xmit program %s for class %s unavailable\n",
  513.                buf[1], buf[0]);
  514.             logerr("(read_config) no xmit for class %s, invalidating class\n",
  515.                buf[0]);
  516.             classptr->valid = 0;
  517.             continue;
  518.          }
  519.  
  520.          (void) strcpy(classptr->xpath, buf[1]);
  521.          for (loop = 2; loop < optioncnt; loop++) {
  522.             Dprintf("class %s: setting xmit parm %d = %s\n",
  523.                classptr->classname, loop - 2, buf[loop]);
  524.             classptr->xargv[loop-2] = (char *) malloc(strlen(buf[loop])+1);
  525.             (void) strcpy(classptr->xargv[loop-2], buf[loop]);
  526.          }
  527.          classptr->xargv[optioncnt - 2] = NULL;
  528.          classptr->xargc = optioncnt - 2;
  529.       }
  530.  
  531.       if ((optioncnt = sscanf(line, "host %s %s %s %s %s %s %s %s", buf[0],
  532.          buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])) > 0) {
  533.  
  534.          Dprintf("optioncnt = %d\n", optioncnt);
  535.  
  536.          interval   = 0;
  537.          startint   = 0;
  538.          maxload    = 0;
  539.          ttl        = 0;
  540.          ttlpenalty = 0;
  541.          deltanice  = 0;
  542.          *buf[9]    = '\0';
  543.  
  544.          for (loop = 3; loop < optioncnt; loop++) {
  545.             (void) sscanf(buf[loop], "maxload=%d", &maxload);
  546.             (void) sscanf(buf[loop], "interval=%d/%d", &interval, &startint);
  547.             (void) sscanf(buf[loop], "ttl=%d/%d", &ttl, &ttlpenalty);
  548.             (void) sscanf(buf[loop], "nice=%d", &deltanice);
  549.             (void) sscanf(buf[loop], "flags=%s", buf[9]);
  550.          }
  551.  
  552.          dprintf("host %s, class %s, times %s, deltanice %d, maxload %d, intvl %d/%d, ttl %d/%d, flags=\"%s\"\n",
  553.                buf[0], buf[1], buf[2], deltanice, maxload, interval, startint,
  554.                ttl, ttlpenalty, buf[9]);
  555.  
  556.          addhost(buf[0], buf[1], buf[2], deltanice, maxload, interval, startint,
  557.                ttl, ttlpenalty, buf[9]);
  558.       }
  559.    }
  560.  
  561.    /*
  562.     * Remove any hosts or classes not defined anymore
  563.     */
  564.  
  565.    clear_invalid();
  566.  
  567.    (void) fclose(config);
  568. }
  569.  
  570. /*************************************************************************/
  571. /* FUNCTION  : dump_config                                               */
  572. /* PURPOSE   : Write the current configuration and status of newsxd to   */
  573. /*             a file                                                    */
  574. /* ARGUMENTS : none                                                      */
  575. /*************************************************************************/
  576.  
  577. void
  578. dump_config()
  579.  
  580. {
  581. struct  host    *hostptr;
  582. struct  class   *classptr;
  583.  
  584. char    lastxmittime[30],          /* bunches of buffers for ctime */
  585.         buf1[30],
  586.         buf2[30],
  587.         pid[30];                /* holds (pid) or "none" */
  588.  
  589. FILE    *status;
  590.  
  591. int    curtime;
  592.  
  593.    if ((debug <= 0) || (DEBUG <= 0)) {
  594.       status = fopen(statusfile, "w");
  595.       if (status == NULL) {
  596.          logerr("Can't open statusfile (%s, \"w\")\n", statusfile);
  597.          return;
  598.       }
  599.    } else
  600.       status = stderr;
  601.  
  602.    curtime = time((long *) NULL);
  603.    (void) fprintf(status, "%s", ctime(&curtime));
  604.    if (daemon_idle) (void) fprintf(status, "Newsxd is idled\n");
  605.  
  606.    if (classlist == NULL) {
  607.       (void) fprintf(status, "No valid classes defined!\n");
  608.       return;
  609.    }
  610.  
  611.    (void) fputc('\n', status);
  612.    foreach (classptr, classlist) {
  613.       if (strcmp(classptr->classname, "DEFAULT") == 0) continue;
  614.  
  615.       (void) fprintf(status, "Class %-7.7s : %2d active transmitters (%2d max)",
  616.          classptr->classname, classptr->curxmits, classptr->maxxmits);
  617.       if (getla() > classptr->options.maxload)
  618.          (void) fprintf(status, " [no new xmits, load %d > %d max]",
  619.             getla(), classptr->options.maxload);
  620.       (void) fputc('\n', status);
  621.    }
  622.  
  623.    (void) fputc('\n', status);
  624.    (void) fprintf(status, "                         Service   Valid Start   Last XMIT  Xmitter  Why Not\n");
  625.    (void) fprintf(status, "Hostname                  Class       Times       Started     pid    Running\n");
  626.    (void) fprintf(status, "-----------------------  -------  -------------  ---------  -------  ----------\n");
  627.  
  628.    if (hostlist == NULL) {
  629.       (void) fprintf(status, "No valid hosts defined!\n");
  630.    }
  631.  
  632.    foreach (hostptr, hostlist) {
  633.       if (hostptr->lasttime == NULL)
  634.          (void) strcpy(lastxmittime, "* NEVER *");
  635.       else {
  636.          (void) sscanf(ctime(&hostptr->lasttime), "%s %*s %*s %s", buf1, buf2);
  637.          (void) sprintf(lastxmittime, "%s %5.5s", buf1, buf2);
  638.       }
  639.  
  640.       (void) sprintf(pid, (hostptr->pid) ? "%d" : "none", hostptr->pid);
  641.  
  642.       (void) fprintf(status, "%-23.23s  %-7s  %-13.13s  %9s   %5s   ",
  643.          hostptr->hostname, hostptr->class, hostptr->times, lastxmittime, pid);
  644.  
  645.       if (daemon_idle && hostptr->whynot != WN_RUNNING)
  646.          (void) fputs("newsxd Idl", status);
  647.       else
  648.          (void) fputs(wnlist[hostptr->whynot], status);
  649.       (void) fputc('\n', status);
  650.    }
  651.    if ((debug <= 0) || (DEBUG <= 0)) (void) fclose(status);
  652. }
  653.  
  654. /*************************************************************************/
  655. /* FUNCTION  : dump_info                                                 */
  656. /* PURPOSE   : Dump newsxd's data structures to a file.                  */
  657. /* ARGUMENTS : none                                                      */
  658. /*************************************************************************/
  659.  
  660. void
  661. dump_info()
  662.  
  663. {
  664. struct  host    *hostptr;
  665. struct    class    *classptr;
  666.  
  667. long    curtime;
  668.  
  669. int    loop, which;
  670.  
  671. FILE    *status;
  672.  
  673. char    outfile[MAXPATHLEN];
  674.  
  675.    if ((debug <= 0) || (DEBUG <= 0)) {
  676.       (void) sprintf(outfile, "%s.dump", statusfile);
  677.       status = fopen(outfile, "w");
  678.       if (status == NULL) {
  679.          logerr("Can't open statusfile (%s, \"w\")\n", statusfile);
  680.          return;
  681.       }
  682.    } else
  683.       status = stderr;
  684.  
  685.    curtime = time((long *) NULL);
  686.  
  687.    (void) fprintf(status, "Newsxd data structures at %s\n", ctime(&curtime));
  688.  
  689.    (void) fprintf(status, "debug is %s, DEBUG is %s, newsxdebug is %s\n",
  690.       debug ? "On" : "Off", DEBUG ? "On" : "Off", newsxdebug ? "On" : "Off");
  691.  
  692.    (void) fprintf(status, "Queue runs occur every %d seconds, newsxd %s idled\n\n",
  693.       queueinterval, daemon_idle ? "IS" : "is not");
  694.  
  695.    (void) fprintf(status, "Active transmitter PID mappings:\n");
  696.  
  697.    which = 0;
  698.    for (loop = 0; loop < MAXXMITTERS; loop++) {
  699.       if (pidlist[loop] != 0) {
  700.          if (!which) (void) fputc('\n', status);
  701.          (void) fprintf(status, "pid %5d --> %-25.25s ", pidlist[loop],
  702.             pidmap[loop]->hostname);
  703.          which = !which;
  704.       }
  705.    }
  706.  
  707.    (void) fputs("\n\n", status);
  708.  
  709.    (void) fprintf(status, "batchfile is                 %s\n", batchfile);
  710.    (void) fprintf(status, "workfile is                  %s\n", workfile);
  711.    (void) fprintf(status, "xmitlogs is                  %s\n", xmitlogs);
  712.    (void) fprintf(status, "newsxd status written to     %s\n", statusfile);
  713.    (void) fprintf(status, "newsxd pid written to        %s\n", pidfile);
  714.    (void) fprintf(status, "newsxd config file is        %s\n", configfile);
  715.    (void) fprintf(status, "\n");
  716.  
  717.    if (classlist == NULL) (void) fprintf(status, "NO DEFINED CLASSES\n");
  718.  
  719.    foreach (classptr, classlist) {
  720.       (void) fprintf(status, "CLASS %s (%02d members)\n\n", classptr->classname,
  721.          classptr->members);
  722.       (void) fprintf(status, "     xmit prog  %s", classptr->xpath);
  723.       for (loop = 0; loop < classptr->xargc; loop++)
  724.          (void) fprintf(status, " %s", classptr->xargv[loop]);
  725.       (void) fprintf(status, "\n");
  726.       (void) fprintf(status, "     xmitters   %02d running, %02d max\n",
  727.          classptr->curxmits, classptr->maxxmits);
  728.       (void) fprintf(status, "     last xmit  %s", ctime(&classptr->laststart));
  729.       (void) fprintf(status, "     sernum     %d\n", classptr->xmitsernum);
  730.  
  731.       (void) fprintf(status, "     options   ");
  732.       if (classptr->options.deltanice)
  733.          (void) fprintf(status, " nice=%d", classptr->options.deltanice);
  734.       if (classptr->options.interval)
  735.          (void) fprintf(status, " interval=%d", classptr->options.interval);
  736.       if (classptr->options.startint)
  737.          (void) fprintf(status, " startint=%d", classptr->options.startint);
  738.       if (classptr->options.ttl)
  739.          (void) fprintf(status, " ttl=%d", classptr->options.ttl);
  740.       if (classptr->options.ttlpenalty)
  741.          (void) fprintf(status, " ttlpenalty=%d", classptr->options.ttlpenalty);
  742.       if (classptr->options.maxload)
  743.          (void) fprintf(status, " maxload=%d", classptr->options.maxload);
  744.  
  745.       (void) fputc('\n', status);
  746.       (void) fprintf(status, "     slots      ");
  747.       for (loop = 0; loop < MAXCLASSXMITTERS; loop++) {
  748.          if ((loop > 0) & ((loop % 50) == 0))
  749.             (void) fputs("\n                ", status);
  750.          (void) fputc(classptr->slots[loop], status);
  751.       }
  752.  
  753.       (void) fputs("\n\n", status);
  754.    }
  755.  
  756.    if (hostlist == NULL) (void) fprintf(status, "NO DEFINED HOSTS\n");
  757.  
  758.    foreach (hostptr, hostlist) {
  759.       (void) fprintf(status, "HOST %s\n", hostptr->hostname);
  760.  
  761.       (void) fprintf(status, "     class      %s\n", hostptr->class);
  762.       (void) fprintf(status, "     xmit times %s\n", hostptr->times);
  763.       (void) fprintf(status, "     xmit pid   %d\n", hostptr->pid);
  764.       (void) fprintf(status, "     last xmit  %s", hostptr->lasttime ? 
  765.          ctime(&hostptr->lasttime) : "NEVER\n");
  766.       (void) fprintf(status, "     penalty to %s", hostptr->penaltytime ?
  767.          ctime(&hostptr->penaltytime) : "NONE\n");
  768.       (void) fprintf(status, "     xmitsernum %d\n", hostptr->xmitsernum);
  769.       (void) fprintf(status, "     whynot     %s (%d)\n", 
  770.          wnlist[hostptr->whynot], hostptr->whynot);
  771.       (void) fprintf(status, "     xmit slot  %d\n", hostptr->classslot);
  772.       (void) fprintf(status, "     xmit flags");
  773.  
  774.       for (loop = 0; loop < hostptr->xargc; loop++)
  775.          (void) fprintf(status, " %s", hostptr->xargv[loop]);
  776.  
  777.       (void) fputc('\n', status);
  778.       (void) fprintf(status, "     options   ");
  779.       if (hostptr->options.deltanice)
  780.          (void) fprintf(status, " nice=%d", hostptr->options.deltanice);
  781.       if (hostptr->options.interval)
  782.          (void) fprintf(status, " interval=%d", hostptr->options.interval);
  783.       if (hostptr->options.startint)
  784.          (void) fprintf(status, " startint=%d", hostptr->options.startint);
  785.       if (hostptr->options.ttl)
  786.          (void) fprintf(status, " ttl=%d", hostptr->options.ttl);
  787.       if (hostptr->options.ttlpenalty)
  788.          (void) fprintf(status, " ttlpenalty=%d", hostptr->options.ttlpenalty);
  789.       if (hostptr->options.maxload)
  790.          (void) fprintf(status, " maxload=%d", hostptr->options.maxload);
  791.  
  792.       (void) fputs("\n\n", status);
  793.    }
  794.  
  795.    if ((debug <= 0) || (DEBUG <= 0)) (void) fclose(status);
  796. }
  797.